﻿/*
    Copyright 2010, 2011 Eric Wong
	contact@optimalcycling.com
	http://www.optimalcycling.com
	Optimal Cycling - Advanced power pacing program for cyclists
	
	This file is part of Optimal Cycling.

    Optimal Cycling is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Optimal Cycling is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Optimal Cycling.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _FILE_KERNELS_H_
#define _FILE_KERNELS_H_

#ifndef __OPENCL_VERSION__
	#include "Options.h"
	#include "Constants.h"
	#include "Vector.h"
	#include "Interpolate.h"
	#include "RandomNumberGen.h"
	#include "Sort.h"
	#include "Integrator.h"
	#include "SolverParams.h"
	#include "Model.h"
	#include "ObjectiveFunc.h"
	#include "PowerMetrics.h"
#endif

/// <summary>
/// The kernel for solving the simulation problem
/// </summary>
/// <param name="currSolutionMode">What mode of the solution phase we are in.</param>
/// <param name="whichArray">Which set of arrays we should use this iteration. (0 = A arrays, 1 = B arrays)</param>
/// <param name="numIndividuals">The number of individual organisms used to solve the problem.</param>
/// <param name="numSimPoints">The number of simulation points, ie: number of data points for a array of data</param>  

/// <param name="powerValA">All the power values from all the individuals condensed into one array.
///		The size of this arrays is numIndividuals * numSimPoints.
///		The starting index for the power genes of an individual is i * numSimPoints where i is the i-th individual starting at zero.</param>
///		The length of a sequence of power genes is numSimPoints.
/// <param name="powerValB">Duplicate of powerValA. Used to eliminate memory allocation during mating.</param>
/// <param name="powerLimits">A 2 variable vector containing the lower and upper limits for the power values (.s0 = lower, .s1 = upper)</param>        
/// <param name="powerAllSame">Whether all the power values should be the same.</param>  

/// <param name="fitness">Array of real indicating the fitness of an individual.</param>
/// <param name="correspondingIndex">Array of uint indicating the corresponding index of the associated genes.</param>
/// <param name="bestFitIndex">The array index for "fitness" pointing to the best individual.</param>
/// <param name="numIndividPerPop">The number of individuals in a population.</param>
/// <param name="numPopulations">The number of populations. Required: numPopulations * numIndividPerPop = numIndividuals</param>

/// <param name="coursePosPoints">A real4 array containing the x, y, z, 0 position points describing the course where y is the vertical. 
///		Size of numSimPoints. [metres]</param>  
/// <param name="coursePosLinear">An array containing the linear course positions starting with 0.
///		Size of numSimPoints. [metres]</param> 
/// <param name="coursePosLinearMax">The value of coursePosLinear[numSimPoints - 1]</param>
/// <param name="coursePosDirection">A real4 array containing the unit direction vector for each point corresponding to coursePosPoints. 
///		Size of numSimPoints. [metres]</param>
/// <param name="coursePosInfo">A real4 array containing the course grade [decimal], rolling resistance coefficient [unitless],
///		the constant of gravity [m/s^2], and course speed limit hight [m/s], corresponding to coursePosLinear.</param>  
/// <param name="wind">A real4 array containing the x, y, z, 0 vector describing the wind. 
///		Size of numSimPoints. [m/s]</param> 
/// <param name="climate">A real4 number array consisting of: 
///     Air Density [kg/m^3], 
///     Air Temperature [Celsius], 
///     Dew Point Temperature [Celsius], 
///     Air Pressure [Pascals] 
///		corresponding to coursePosLinear.</param>  

/// <param name="dragCoeffWheelYawAngles">A real array containing the yaw angles for the wheel drag coefficients.
///		From [0, Pi] radians. Size of dragCoeffWheelsNumPts.</param>
/// <param name="dragCoeffWheels">A real2 array containing the front wheel drag coefficient [unitless],
///		rear wheel drag coefficient [unitless]. Size of dragCoeffWheelsNumPts.</param>  
/// <param name="dragCoeffWheelsNumPts">The number of wheel drag coefficient data points.</param>

/// <param name="modelInfo">Various model parameters.</param>        
/// <param name="iConstants">Various integration constants.</param> 
/// <param name="randNumGenSeeds">A uint4 array containing randomized seeds for the random number generator.
///		Size of numIndividuals. [metres]</param> 

/// <param name="solverInfo">Various solver solver parameters.</param>
/// <param name="solverVars">Various parameters for evaluating the fitness of an individual.</param>

/// <param name="bestTime">The best time found. Length of 1. [sec]</param>  
/// <param name="bestPowerResults">Length of 1, {s0} Energy sum [J], {s1} Average power [watts], {s2} CCAP [watts], {s3} CCAP critical [watts]</param>   
/// <param name="bestKinematics">Length of numSimPoints, {s0} power values [watts], {s1} Time points [sec], {s2} speed [m/s], {s3} acceleration [m/s^2]</param>  

/// <param name="fitStats">Contains the average fitness and the number of viable individuals.</param> 

/// <returns>Check bestTime, bestPowerResults, and bestKinematics for the results.</returns>

#ifdef _USRDLL
//extern "C"
//{
	__declspec(dllexport)
#endif
__kernel void
OCSimRun(
	const int currSolutionMode, 
    const int whichArray,
	const sizeT numIndividuals,
	const sizeT numSimPoints,
	  
	__global real* powerValA, 
	__global real* powerValB,
	__global const real2* powerLimits,
	const int powerAllSame, 

	__global real* fitness,
	__global sizeT* correspondingIndex,
	__global sizeT* bestFitIndex,
	const sizeT numIndividPerPop, 
	const sizeT numPopulations,

	__global const real4* coursePosPoints,
	__global const real* coursePosLinear,
	const real coursePosLinearMax,
	__global const real4* coursePosDirection,
	__global const real4* coursePosInfo,
	__global const real4* riderProp,
	__global const real4* wind, 
	__global const real4* climate,

	__global const real* dragCoeffWheelYawAngles,
	__global const real2* dragCoeffWheels, 
	const sizeT dragCoeffWheelsNumPts,

	__global const ModelInfo* modelInfo, 
	__global const real4* iConstants,

	__global uint4* randNumGenSeeds,
	__global const SolverInfo* solverInfo,
	__global SolverVars* solverVars,
	__global const PowerMetricsInfo* powerMetricsInfo,
	__global const real2* powerMetricsCriticals,

	__global real* tempWorkingSpace,

	__global real* bestTime,
	__global real8* bestPowerResults,
	__global real8* bestKinematics,

	__global real2* fitStats);

#endif		// _FILE_KERNELS_H_

#ifdef _USRDLL
//}
#endif

